'use strict';

const Service = require('egg').Service;
const fs = require('fs');
const path = require('path');
const { v4: uuidv4 } = require('uuid');

// 尝试加载sharp，如果失败则使用fallback
let sharp;
try {
  sharp = require('sharp');
} catch (error) {
  console.warn('Sharp not available, using fallback image processing');
  sharp = null;
}

class UploadService extends Service {
  // 上传图片
  async uploadImage(file, type = 'general') {
    const { ctx, app } = this;
    
    try {
      // 验证文件类型
      const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
      if (!allowedTypes.includes(file.mimeType)) {
        throw new Error('不支持的文件类型');
      }
      
      // 验证文件大小 (50MB)
      const maxSize = 50 * 1024 * 1024;
      if (file.size > maxSize) {
        throw new Error('文件大小超过限制');
      }
      
      // 生成文件名
      const ext = path.extname(file.filename);
      const filename = `${uuidv4()}${ext}`;
      
      // 创建目录结构
      const uploadDir = path.join(app.baseDir, app.config.uploadDir, type);
      const dateDir = new Date().toISOString().slice(0, 7); // YYYY-MM
      const targetDir = path.join(uploadDir, dateDir);
      
      if (!fs.existsSync(targetDir)) {
        fs.mkdirSync(targetDir, { recursive: true });
      }
      
      const targetPath = path.join(targetDir, filename);
      const relativePath = path.join('uploads', type, dateDir, filename).replace(/\\/g, '/');
      
      // 处理图片
      await this.processImage(file.filepath, targetPath);
      
      // 清理临时文件
      fs.unlinkSync(file.filepath);
      
      return `/public/${relativePath}`;
    } catch (error) {
      // 清理临时文件
      if (file.filepath && fs.existsSync(file.filepath)) {
        fs.unlinkSync(file.filepath);
      }
      throw error;
    }
  }

  // 处理图片（压缩、格式转换等）
  async processImage(inputPath, outputPath, options = {}) {
    if (!sharp) {
      // 如果sharp不可用，直接复制文件
      fs.copyFileSync(inputPath, outputPath);
      return true;
    }

    const {
      width = 1200,
      height = 1200,
      quality = 85,
      format = 'jpeg',
    } = options;

    try {
      let processor = sharp(inputPath);

      // 获取图片信息
      const metadata = await processor.metadata();

      // 如果图片尺寸超过限制，进行缩放
      if (metadata.width > width || metadata.height > height) {
        processor = processor.resize(width, height, {
          fit: 'inside',
          withoutEnlargement: true,
        });
      }

      // 转换格式和压缩
      if (format === 'jpeg') {
        processor = processor.jpeg({ quality });
      } else if (format === 'png') {
        processor = processor.png({ quality });
      } else if (format === 'webp') {
        processor = processor.webp({ quality });
      }

      await processor.toFile(outputPath);

      return true;
    } catch (error) {
      throw new Error(`图片处理失败: ${error.message}`);
    }
  }

  // 生成缩略图
  async generateThumbnail(imagePath, thumbnailPath, size = 300) {
    if (!sharp) {
      // 如果sharp不可用，直接复制原图
      fs.copyFileSync(imagePath, thumbnailPath);
      return true;
    }

    try {
      await sharp(imagePath)
        .resize(size, size, {
          fit: 'cover',
          position: 'center',
        })
        .jpeg({ quality: 80 })
        .toFile(thumbnailPath);

      return true;
    } catch (error) {
      throw new Error(`缩略图生成失败: ${error.message}`);
    }
  }

  // 批量上传图片
  async uploadMultipleImages(files, type = 'general') {
    const results = [];
    
    for (const file of files) {
      try {
        const url = await this.uploadImage(file, type);
        results.push({
          success: true,
          url,
          filename: file.filename,
        });
      } catch (error) {
        results.push({
          success: false,
          error: error.message,
          filename: file.filename,
        });
      }
    }
    
    return results;
  }

  // 删除文件
  async deleteFile(filePath) {
    try {
      const fullPath = path.join(this.app.baseDir, 'app/public', filePath.replace('/public/', ''));
      
      if (fs.existsSync(fullPath)) {
        fs.unlinkSync(fullPath);
        return true;
      }
      
      return false;
    } catch (error) {
      throw new Error(`文件删除失败: ${error.message}`);
    }
  }

  // 获取文件信息
  async getFileInfo(filePath) {
    try {
      const fullPath = path.join(this.app.baseDir, 'app/public', filePath.replace('/public/', ''));
      
      if (!fs.existsSync(fullPath)) {
        throw new Error('文件不存在');
      }
      
      const stats = fs.statSync(fullPath);
      const ext = path.extname(fullPath).toLowerCase();
      
      let metadata = null;
      if (sharp && ['.jpg', '.jpeg', '.png', '.gif', '.webp'].includes(ext)) {
        try {
          metadata = await sharp(fullPath).metadata();
        } catch (error) {
          // 忽略metadata获取错误
        }
      }
      
      return {
        size: stats.size,
        created: stats.birthtime,
        modified: stats.mtime,
        extension: ext,
        metadata,
      };
    } catch (error) {
      throw new Error(`获取文件信息失败: ${error.message}`);
    }
  }

  // 图片颜色分析
  async analyzeImageColors(imagePath) {
    if (!sharp) {
      // 如果sharp不可用，返回默认颜色
      return {
        rgb: [128, 128, 128],
        hex: '#808080',
      };
    }

    try {
      const { dominant } = await sharp(imagePath).stats();

      // 提取主要颜色
      const colors = dominant.map(channel => Math.round(channel));
      const hexColor = `#${colors.map(c => c.toString(16).padStart(2, '0')).join('')}`;

      return {
        rgb: colors,
        hex: hexColor,
      };
    } catch (error) {
      throw new Error(`颜色分析失败: ${error.message}`);
    }
  }

  // 图片背景移除（需要AI服务支持）
  async removeBackground(imagePath) {
    // 这里可以集成第三方背景移除服务
    // 如 remove.bg API 或其他AI服务
    throw new Error('背景移除功能暂未实现');
  }

  // 清理过期文件
  async cleanupExpiredFiles(days = 30) {
    const uploadDir = path.join(this.app.baseDir, this.app.config.uploadDir);
    const expireTime = Date.now() - (days * 24 * 60 * 60 * 1000);
    
    let deletedCount = 0;
    
    const cleanDirectory = (dir) => {
      if (!fs.existsSync(dir)) return;
      
      const files = fs.readdirSync(dir);
      
      for (const file of files) {
        const filePath = path.join(dir, file);
        const stats = fs.statSync(filePath);
        
        if (stats.isDirectory()) {
          cleanDirectory(filePath);
          
          // 如果目录为空，删除目录
          const remainingFiles = fs.readdirSync(filePath);
          if (remainingFiles.length === 0) {
            fs.rmdirSync(filePath);
          }
        } else if (stats.mtime.getTime() < expireTime) {
          fs.unlinkSync(filePath);
          deletedCount++;
        }
      }
    };
    
    cleanDirectory(uploadDir);
    
    return {
      deletedCount,
      message: `清理了 ${deletedCount} 个过期文件`,
    };
  }
}

module.exports = UploadService;
